from rest_framework.response import Response
from rest_framework.decorators import action

from django.core.cache import cache

from usercenter.common.errors import get_error_info, MOBILEPHONE_ERROR,\
    CODE_INVALID_ERROR, EMAIL_ERROR, EMAIL_PASSWORD_ERROR
from usercenter.common.redis_keys import PHONE_CODE_KEY, CAPTCHA_CODE_KEY
from usercenter.common.validators import validate_mobilephone, validate_email

from rest_framework import viewsets
from usercenter.models import CustomerProfile
from usercenter.utils.captcha_util import captcha_cls
from .serializers import PhoneLoginSerializer
from .base.user import get_customer_user, create_customer_user, get_user_info, get_user_by_id, get_password_hash
from .base.token import create_token
from .base.jwt_authentication import ZXAuthentication

import logging
logger = logging.getLogger('userauth')


class PhoneAuthViewSet(viewsets.GenericViewSet):
    """
    """
    queryset = CustomerProfile.objects.all()
    serializer_class = PhoneLoginSerializer
    permission_classes = ()

    @action(methods=['post'], detail=False)
    def login(self, request, **kwargs):
        """
        手机登录或创建用户
        """
        ret = {'code': 0, 'message': '', 'user_info': None, 'token': ''}
        self.get_serializer().run_validation(request.data)  # 验证输入

        phone = request.data.get('phone', '').strip()
        code = request.data.get('code', '').strip()
        if not validate_mobilephone(phone):
            ret.update(get_error_info(MOBILEPHONE_ERROR))  # 手机号错误
            return Response(ret, 400)

        res = cache.get(PHONE_CODE_KEY % phone, )
        if not res or res != code:
            ret.update(get_error_info(CODE_INVALID_ERROR))  # 验证码错误
            return Response(ret, 400)

        # 手机校验完成
        user = get_customer_user(cellphone=phone)
        user_info = {}
        if not user:  # 创建用户
            user_info = {'cellphone': phone}
            user = create_customer_user(user_info=user_info)

        ret['token'] = create_token(user)
        ret['user_info'] = user_info or get_user_info(user.id)

        return Response(ret)


class EmailAuthViewSet(viewsets.GenericViewSet):
    """
    """
    queryset = CustomerProfile.objects.all()
    serializer_class = PhoneLoginSerializer
    permission_classes = ()

    @action(methods=['post'], detail=False)
    def login(self, request, **kwargs):
        """
        Email登录
        """
        ret = {'code': 0, 'message': '', 'user_info': None, 'token': ''}
        self.get_serializer().run_validation(request.data)  # 验证输入

        email = request.data.get('email', '').strip()
        password = request.data.get('password', '').strip()

        # code start?
        captcha_code = request.data.get('code', '').strip()
        res = cache.get(CAPTCHA_CODE_KEY % email, )
        if not res or res != captcha_code:
            ret.update(get_error_info(CODE_INVALID_ERROR))  # 验证码错误
            return Response(ret, 400)
        # code end?

        if not validate_email(email):
            ret.update(get_error_info(EMAIL_ERROR))  # email错误
            return Response(ret, 400)

        password_hash = get_password_hash(password=password)
        user = get_customer_user(email=email)
        if not user or password_hash != user.password:
            ret.update(get_error_info(EMAIL_PASSWORD_ERROR))  # email 密码错误
            return Response(ret, 400)

        ret['token'] = create_token(user)
        ret['user_info'] = get_user_info(user.id)

        return Response(ret)

    @action(methods=['post'], detail=False)
    def create(self, request, **kwargs):
        """
        Email 注册
        """
        ret = {'code': 0, 'message': '', 'user_info': None, 'token': ''}
        self.get_serializer().run_validation(request.data)  # 验证输入

        email = request.data.get('email', '').strip()
        password = request.data.get('password', '').strip()

        # code start?
        code = request.data.get('code', '').strip()
        res = cache.get(CAPTCHA_CODE_KEY % email, )
        if not res or res != code:
            ret.update(get_error_info(CODE_INVALID_ERROR))  # 验证码错误
            return Response(ret, 400)
        # code end?

        if not validate_email(email):
            ret.update(get_error_info(EMAIL_ERROR))  # email错误
            return Response(ret, 400)

        password_hash = get_password_hash(password=password)
        user_info = {'email': email,
                     'password': password_hash,
                     }
        user = create_customer_user(user_info)  # 新建用户

        ret['token'] = create_token(user)
        ret['user_info'] = get_user_info(user.id)

        return Response(ret)


class CheckAuthViewSet(viewsets.GenericViewSet):
    """
    """
    queryset = CustomerProfile.objects.all()
    serializer_class = None
    permission_classes = ()

    @action(methods=['get'], detail=False)
    def check(self, request, **kwargs):
        """
        检查客户是否登录
        """
        ret = {'code': 0, 'message': '', 'user_info': None}
        user_info, _ = ZXAuthentication().authenticate(request)
        ret['user_info'] = user_info
        return Response(ret)

    @action(methods=['get'], detail=False)
    def refresh(self, request, **kwargs):
        """
        refresh Customer user token
        """
        ret = {'code': 0, 'message': '', 'user_info': None}
        user_info, _ = ZXAuthentication().authenticate(request)
        ret['user_info'] = user_info
        user = get_user_by_id(id=user_info['user_id'])
        ret['token'] = create_token(user)
        return Response(ret)


class CaptchaViewSet(viewsets.GenericViewSet):
    """
    """
    queryset = CustomerProfile.objects.all()
    serializer_class = None
    permission_classes = ()

    def list(self, request, **kwargs):
        """
        captcha
        """
        ret = {'code': 0, 'message': '', 'data': {}}
        res = captcha_cls.get_captcha()
        code = res.pop('code')
        cache.get(CAPTCHA_CODE_KEY % res['uuid'], code)
        ret['data'] = res
        return Response(ret)
